/**
 * @file protocol_manager_main.c
 * @brief 协议管理器主程序
 * @details 统一入口，负责启动和管理所有协议网关
 * 
 * @author zyb
 * @date 2025-10-30
 * @version 1.0
 */

#define _POSIX_C_SOURCE 200809L

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <getopt.h>
#include "../../../common/logs/include/logger.h"
#include "../include/protocol_manager.h"

// 日志模块名称
#define LOG_MODULE_NAME "PROTOCOL_MANAGER"

// 全局变量
static volatile bool g_running = true;
static protocol_manager_config_t g_config;
static pid_t g_protocol_pids[PROTOCOL_TYPE_MAX] = {0};

/* ==================== 信号处理 ==================== */

/**
 * @brief 信号处理函数
 */
static void signal_handler(int signo) {
    if (signo == SIGINT || signo == SIGTERM) {
        LOG_INFO(LOG_MODULE_NAME, "收到退出信号 %d，准备关闭所有协议...", signo);
        g_running = false;
    } else if (signo == SIGCHLD) {
        // 子进程退出处理
        int status;
        pid_t pid;
        while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
            if (WIFEXITED(status)) {
                LOG_WARN(LOG_MODULE_NAME, "子进程 %d 退出，状态码: %d", 
                        pid, WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                LOG_ERROR(LOG_MODULE_NAME, "子进程 %d 被信号 %d 终止", 
                         pid, WTERMSIG(status));
            }
        }
    }
}

/**
 * @brief 设置信号处理
 */
static void setup_signal_handlers(void) {
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGCHLD, signal_handler);
    signal(SIGPIPE, SIG_IGN);
}

/* ==================== 配置加载 ==================== */

/**
 * @brief 加载管理器配置
 */
static int load_config(const char* config_file) {
    LOG_INFO(LOG_MODULE_NAME, "加载配置文件: %s", config_file);
    
    // 初始化配置
    memset(&g_config, 0, sizeof(protocol_manager_config_t));
    
    // 默认配置
    strncpy(g_config.log_file, "logs/protocol_manager.log", sizeof(g_config.log_file) - 1);
    g_config.log_level = LOG_LEVEL_INFO;
    
    // 默认启用IEC104协议
    g_config.protocol_count = 1;
    g_config.protocols[0].type = PROTOCOL_TYPE_IEC104;
    g_config.protocols[0].enabled = true;
    strncpy(g_config.protocols[0].config_file, 
            "protocol/104/controller/config/iec104_controller.conf",
            sizeof(g_config.protocols[0].config_file) - 1);
    
    LOG_INFO(LOG_MODULE_NAME, "配置加载完成");
    LOG_INFO(LOG_MODULE_NAME, "  启用协议数: %u", g_config.protocol_count);
    
    return 0;
}

/* ==================== 协议管理 ==================== */

/**
 * @brief 启动IEC104协议控制器
 */
static int start_iec104_gateway(const char* config_file) {
    pid_t pid = fork();
    
    if (pid < 0) {
        LOG_ERROR(LOG_MODULE_NAME, "创建IEC104控制器进程失败");
        return -1;
    } else if (pid == 0) {
        // 子进程：执行IEC104控制器
        char* args[] = {
            "build/protocol/104/controller/bin/iec104_controller_app",
            "-c",
            (char*)config_file,
            NULL
        };
        
        execv(args[0], args);
        
        // 如果execv返回，说明执行失败
        LOG_ERROR(LOG_MODULE_NAME, "启动IEC104控制器失败");
        exit(1);
    } else {
        // 父进程：记录PID
        g_protocol_pids[PROTOCOL_TYPE_IEC104] = pid;
        LOG_INFO(LOG_MODULE_NAME, "成功 IEC104控制器已启动 (PID: %d)", pid);
        return 0;
    }
}

/**
 * @brief 启动协议
 */
static int start_protocol(protocol_type_t type, const char* config_file) {
    switch (type) {
        case PROTOCOL_TYPE_IEC104:
            return start_iec104_gateway(config_file);
        
        default:
            LOG_ERROR(LOG_MODULE_NAME, "未知或未实现的协议类型: %d", type);
            return -1;
    }
}

/**
 * @brief 停止协议网关
 */
static int stop_protocol(protocol_type_t type) {
    pid_t pid = g_protocol_pids[type];
    
    if (pid > 0) {
        LOG_INFO(LOG_MODULE_NAME, "停止协议 %d (PID: %d)", type, pid);
        kill(pid, SIGTERM);
        
        // 等待进程退出
        int status;
        waitpid(pid, &status, 0);
        
        g_protocol_pids[type] = 0;
        LOG_INFO(LOG_MODULE_NAME, "协议 %d 已停止", type);
    }
    
    return 0;
}

/* ==================== 主函数 ==================== */

/**
 * @brief 打印使用说明
 */
static void print_usage(const char* program) {
    printf("协议管理器 - Protocol Manager\n");
    printf("用法: %s [选项]\n", program);
    printf("选项:\n");
    printf("  -c <config>  指定配置文件 (默认: config/manager.conf)\n");
    printf("  -h           显示此帮助信息\n");
    printf("  -v           显示版本信息\n");
}

/**
 * @brief 打印版本信息
 */
static void print_version(void) {
    printf("协议管理器 v1.0.0\n");
    printf("统一管理IEC 104、Modbus、OPC UA等多种协议\n");
}

/**
 * @brief 主函数
 */
int main(int argc, char* argv[]) {
    const char* config_file = "config/manager.conf";
    int opt;
    
    // 解析命令行参数
    while ((opt = getopt(argc, argv, "c:hv")) != -1) {
        switch (opt) {
            case 'c':
                config_file = optarg;
                break;
            case 'h':
                print_usage(argv[0]);
                return 0;
            case 'v':
                print_version();
                return 0;
            default:
                print_usage(argv[0]);
                return 1;
        }
    }
    
    // 设置信号处理
    setup_signal_handlers();
    
    // 初始化日志系统
    if (logger_init() != 0) {
        fprintf(stderr, "日志系统初始化失败\n");
        return 1;
    }
    
    // 配置日志系统
    logger_config_t log_config = {0};
    log_config.level = LOG_LEVEL_INFO;
    log_config.console_output = true;
    log_config.file_output = true;
    log_config.timestamp = true;
    log_config.module_name = true;
    strncpy(log_config.log_file, "logs/protocol_manager.log", sizeof(log_config.log_file) - 1);
    
    if (logger_configure(&log_config) != 0) {
        fprintf(stderr, "日志系统配置失败\n");
        logger_cleanup();
        return 1;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    LOG_INFO(LOG_MODULE_NAME, "协议管理器启动");
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    
    // 加载配置
    if (load_config(config_file) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "加载配置失败");
        logger_cleanup();
        return 1;
    }
    
    // 启动所有已启用的协议
    for (uint32_t i = 0; i < g_config.protocol_count; i++) {
        protocol_config_t* proto = &g_config.protocols[i];
        
        if (proto->enabled) {
            LOG_INFO(LOG_MODULE_NAME, "启动协议 %d: %s", 
                    proto->type, proto->config_file);
            
            if (start_protocol(proto->type, proto->config_file) != 0) {
                LOG_ERROR(LOG_MODULE_NAME, "启动协议 %d 失败", proto->type);
            }
        }
    }
    
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    LOG_INFO(LOG_MODULE_NAME, "成功 协议管理器运行中，按Ctrl+C退出...");
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    
    // 主循环
    while (g_running) {
        sleep(1);
    }
    
    // 停止所有协议
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    LOG_INFO(LOG_MODULE_NAME, "正在停止所有协议...");
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    
    for (uint32_t i = 0; i < PROTOCOL_TYPE_MAX; i++) {
        if (g_protocol_pids[i] > 0) {
            stop_protocol((protocol_type_t)i);
        }
    }
    
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    LOG_INFO(LOG_MODULE_NAME, "成功 协议管理器已关闭");
    LOG_INFO(LOG_MODULE_NAME, "========================================");
    
    logger_cleanup();
    
    return 0;
}

